function mxRubberband(a) {
    if (a != null) {
        this.graph = a;
        this.graph.addMouseListener(this);
        this.panHandler = mxUtils.bind(this,
        function() {
            this.repaint()
        });
        this.graph.addListener(mxEvent.PAN, this.panHandler);
        mxClient.IS_IE && mxEvent.addListener(window, "unload", mxUtils.bind(this,
        function() {
            this.destroy()
        }))
    }
}
mxRubberband.prototype.defaultOpacity = 20;
mxRubberband.prototype.enabled = !0;
mxRubberband.prototype.div = null;
mxRubberband.prototype.sharedDiv = null;
mxRubberband.prototype.currentX = 0;
mxRubberband.prototype.currentY = 0;
mxRubberband.prototype.isEnabled = function() {
    return this.enabled
};
mxRubberband.prototype.setEnabled = function(a) {
    this.enabled = a
};
mxRubberband.prototype.mouseDown = function(a, b) {
    if (!b.isConsumed() && this.isEnabled() && this.graph.isEnabled() && (this.graph.isForceMarqueeEvent(b.getEvent()) || b.getState() == null)) {
        var c = mxUtils.getOffset(this.graph.container),
        d = mxUtils.getScrollOrigin(this.graph.container);
        d.x = d.x - c.x;
        d.y = d.y - c.y;
        this.start(b.getX() + d.x, b.getY() + d.y);
        if (mxClient.IS_NS && !mxClient.IS_SF && !mxClient.IS_GC) {
            var e = this.graph.container,
            f = function(a) {
                var a = new mxMouseEvent(a),
                b = mxUtils.convertPoint(e, a.getX(), a.getY());
                a.graphX = b.x;
                a.graphY = b.y;
                return a
            };
            this.dragHandler = mxUtils.bind(this,
            function(a) {
                this.mouseMove(this.graph, f(a))
            });
            this.dropHandler = mxUtils.bind(this,
            function(a) {
                this.mouseUp(this.graph, f(a))
            });
            mxEvent.addListener(document, "mousemove", this.dragHandler);
            mxEvent.addListener(document, "mouseup", this.dropHandler)
        }
        b.consume(false)
    }
};
mxRubberband.prototype.start = function(a, b) {
    this.first = new mxPoint(a, b)
};
mxRubberband.prototype.mouseMove = function(a, b) {
    if (!b.isConsumed() && this.first != null) {
        var c = mxUtils.getScrollOrigin(this.graph.container),
        d = mxUtils.getOffset(this.graph.container);
        c.x = c.x - d.x;
        c.y = c.y - d.y;
        var d = b.getX() + c.x,
        c = b.getY() + c.y,
        e = this.first.x - d,
        f = this.first.y - c,
        g = this.graph.tolerance;
        if (this.div != null || Math.abs(e) > g || Math.abs(f) > g) {
            if (this.div == null) this.div = this.createShape();
            mxUtils.clearSelection();
            this.update(d, c);
            b.consume()
        }
    }
};
mxRubberband.prototype.createShape = function() {
    if (this.sharedDiv == null) {
        this.sharedDiv = document.createElement("div");
        this.sharedDiv.className = "mxRubberband";
        mxUtils.setOpacity(this.sharedDiv, this.defaultOpacity)
    }
    this.graph.container.appendChild(this.sharedDiv);
    return this.sharedDiv
};
mxRubberband.prototype.mouseUp = function(a, b) {
    var c = this.div != null;
    this.reset();
    if (c) {
        this.graph.selectRegion(new mxRectangle(this.x, this.y, this.width, this.height), b.getEvent());
        b.consume()
    }
};
mxRubberband.prototype.reset = function() {
    this.div != null && this.div.parentNode.removeChild(this.div);
    if (this.dragHandler != null) {
        mxEvent.removeListener(document, "mousemove", this.dragHandler);
        this.dragHandler = null
    }
    if (this.dropHandler != null) {
        mxEvent.removeListener(document, "mouseup", this.dropHandler);
        this.dropHandler = null
    }
    this.currentY = this.currentX = 0;
    this.div = this.first = null
};
mxRubberband.prototype.update = function(a, b) {
    this.currentX = a;
    this.currentY = b;
    this.repaint()
};
mxRubberband.prototype.repaint = function() {
    if (this.div != null) {
        var a = this.currentX - this.graph.panDx,
        b = this.currentY - this.graph.panDy;
        this.x = Math.min(this.first.x, a);
        this.y = Math.min(this.first.y, b);
        this.width = Math.max(this.first.x, a) - this.x;
        this.height = Math.max(this.first.y, b) - this.y;
        a = mxClient.IS_VML ? this.graph.panDy: 0;
        this.div.style.left = this.x + (mxClient.IS_VML ? this.graph.panDx: 0) + "px";
        this.div.style.top = this.y + a + "px";
        this.div.style.width = Math.max(1, this.width) + "px";
        this.div.style.height = Math.max(1, this.height) + "px"
    }
};
mxRubberband.prototype.destroy = function() {
    if (!this.destroyed) {
        this.destroyed = true;
        this.graph.removeMouseListener(this);
        this.graph.removeListener(this.panHandler);
        this.reset();
        if (this.sharedDiv != null) this.sharedDiv = null
    }
};